#include "stdafx.h"
#include "SliderCtrlEx.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

IMPLEMENT_DYNAMIC(CSliederCtrlEx, CSliderCtrl)

BEGIN_MESSAGE_MAP(CSliederCtrlEx, CSliderCtrl)
	//{{AFX_MSG_MAP(CSliederCtrlEx)
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


void CSliederCtrlEx::OnLButtonDown(UINT nFlags, CPoint point) 
{
     m_Dragging = true;
     m_DragChanged = false;
     SetCapture();
     SetFocus();
     if (SetThumb(point))
     {
	     m_DragChanged = true;
	     PostMessageToParent(SB_THUMBTRACK);
     }
}


void CSliederCtrlEx::OnMouseMove(UINT nFlags, CPoint point) 
{
     if (m_Dragging)
     {
	     if (SetThumb(point))
	     {
		     m_DragChanged = true;
		     PostMessageToParent(SB_THUMBTRACK);
	     }
     }
     else
     {
	     CSliderCtrl::OnMouseMove(nFlags, point);
     }
}

void CSliederCtrlEx::OnLButtonUp(UINT nFlags, CPoint point) 
{
     if( m_Dragging )
     {
	     m_Dragging = false;
	     ::ReleaseCapture();
	     if (SetThumb(point))
	     {
		     PostMessageToParent(SB_THUMBTRACK);
		     m_DragChanged = true;
	     }
	     if (m_DragChanged)
	     {
		     PostMessageToParent(SB_THUMBPOSITION);
		     m_DragChanged = false;
	     }
                
        PostMessageToParent(SB_THUMBTRACK);
     }
     else
     {
	     CSliderCtrl::OnLButtonUp(nFlags, point);
     }
}


bool CSliederCtrlEx::SetThumb(const CPoint& point)
{
     const int nMin = GetRangeMin();
     const int nMax = GetRangeMax()+1;
     CRect rc;
     GetChannelRect(rc);
     double dPos;
     double dCorrectionFactor = 0.0;
     if (GetStyle() & TBS_VERT) 
     {
	     // note: there is a bug in GetChannelRect, it gets the orientation of the rectangle mixed up
	     dPos = (double)(point.y - rc.left)/(rc.right - rc.left);
     }
     else
     {
	     dPos = (double)(point.x - rc.left)/(rc.right - rc.left);
     }
     // This correction factor is needed when you click inbetween tick marks
     // so that the thumb will move to the nearest one
     dCorrectionFactor = 0.5 *(1-dPos) - 0.5 *dPos;
     int nNewPos = (int)(nMin + (nMax-nMin)*dPos + dCorrectionFactor);
     const bool bChanged = (nNewPos != GetPos());
     if(bChanged)
     {
	     SetPos(nNewPos);
     }
     return bChanged;
}

void CSliederCtrlEx::PostMessageToParent(const int nTBCode) const
{
     CWnd* pWnd = GetParent();
     if(pWnd) pWnd->PostMessage(WM_HSCROLL, (WPARAM)((GetPos() << 16) | nTBCode), (LPARAM)GetSafeHwnd());
}


